package cn.org.wifit.core.zookeeper.watcher;

import java.util.List;
import java.util.regex.Pattern;

import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.Watcher.Event.EventType;
import org.apache.zookeeper.ZooKeeper;

import cn.org.wifit.core.zookeeper.NodeReadWatcherHandle;

/**
 * Zookeeper上IMServer节点状态的管理器，用途包括：
 * 监听zookeeper节点上IMServer节点的变化：<br>
 * 1、以便在新增IMServer集群后，调用NodeWriteFactory来更新IMUser节点中的MaxID属性【只有对应的/IMServer/Server/IPX序号最小的节点才需要这么做】。并且更新本地内存中IMServer的相关信息。<br>
 * 2、以便在新增/退出IMServer某个具体服务子节点后，更新本地内存中IMServer的相关信息。
 * @author yinwenjie
 */
public class IMServerWatcher implements Watcher {
	
	private ZooKeeper zk;
	
	private NodeReadWatcherHandle watcherHandle;
	
	public IMServerWatcher() {
		
	}
	
	/* (non-Javadoc)
	 * @see org.apache.zookeeper.Watcher#process(org.apache.zookeeper.WatchedEvent)
	 */
	@Override
	public void process(WatchedEvent event) {
		System.out.println("IMServerWatcher.process(WatchedEvent event)");
		if(!this.zk.getState().isConnected()) {
			return;
		}
		
		//==================重新进行监听的注册
		try {
			List<String> serverList = this.zk.getChildren("/IMServer", this);
			for (String serverpath : serverList) {
				this.zk.exists("/IMServer/" + serverpath, this);
				this.zk.getChildren("/IMServer/" + serverpath, this);
			}
		} catch (Exception e) {
			e.printStackTrace(System.out);
		}
		
		String eventPath = event.getPath();
		System.out.println("eventPath = " + eventPath);
		System.out.println("event = " + event);
		
		/*
		 * 这里需要判断几种情况
		 * 1、/IMServer/server/ipx新增或减少时，NodeChildrenChanged类型被触发，调用watcherHandle接口的doIpxChanged(String parentPath)方法
		 * 2、/IMServer/server新增或减少时，NodeChildrenChanged类型被触发，调用watcherHandle接口的doServerChanged(String eventPath)方法
		 * */
		if(event.getType() != EventType.NodeChildrenChanged) {
			System.out.println(event + " 事件没有处理 ");
			return;
		}
		
		//满足以下正则式，表示是某一个ipx节点发生了变化
		Pattern pattern = Pattern.compile("^/IMServer/server[0-9]{10}$");
		if(pattern.matcher(event.getPath()).find()) {
			try {
				this.watcherHandle.doServerIpxChanged(event.getPath());
			} catch(Exception e) {
				e.printStackTrace(System.out);
			}
		} 
		
		pattern = Pattern.compile("^/IMServer$");
		if(pattern.matcher(event.getPath()).find()) {
			try {
				this.watcherHandle.doServerChanged();
			} catch(Exception e) {
				e.printStackTrace(System.out);
			}
		} 
	}

	public ZooKeeper getZk() {
		return zk;
	}

	public void setZk(ZooKeeper zk) {
		this.zk = zk;
	}

	public NodeReadWatcherHandle getWatcherHandle() {
		return watcherHandle;
	}

	public void setWatcherHandle(NodeReadWatcherHandle watcherHandle) {
		this.watcherHandle = watcherHandle;
	}
}